class commitment {
    static PENDING = '待定'; static FULLFILLED = '通过'; static REJECTED = '拒绝';
    constructor(func){
        this.status = commitment.PENDING;
        this.result = null;
        this.resolveCallbacks = [];
        this.rejectCallbacks = [];

        try {
            func(this.resolve.bind(this), this.reject.bind(this));
        } catch (e) {
            this.reject(e);
        }
    }

    resolve(result){
        setTimeout(() => {
            if(this.status === commitment.PENDING){
                this.status = commitment.FULLFILLED;
                this.result = result;
                this.resolveCallbacks.forEach(cb => cb(result));
            }
        });
    }
    reject(result){
        setTimeout(() => {
            if(this.status === commitment.PENDING){
                this.status = commitment.REJECTED;
                this.result = result;
                this.rejectCallbacks.forEach(cb => cb(result));
            }
        });
    }

    then(onFULLFILLED, onREJECTED){

        return new commitment((resolve, reject) => {

                    onFULLFILLED = typeof onFULLFILLED === 'function' ? onFULLFILLED : (result) => result;
                    onREJECTED = typeof onREJECTED === 'function' ? onREJECTED : (result) => {throw result};

                    if(this.status === commitment.FULLFILLED){
                        onFULLFILLED(this.result);
                    }
                    if(this.status === commitment.REJECTED){
                        onREJECTED(this.result);
                    }
                    if(this.status === commitment.PENDING){
                        this.resolveCallbacks.push(onFULLFILLED);
                        this.rejectCallbacks.push(onREJECTED);
                    }
                });
    }
}

let cmt = new commitment(function(resolve, reject){
    setTimeout(() => {
        resolve('success');
    }, 1000);
});
cmt.then(result => console.log(result), result => console.log(result.message))
.then(result => console.log(result), result => console.log(result.message));